﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Medianamik.Core
{
    /// <summary>
    /// Cette classe représente une relation OneToMany entre deux Types
    /// <example>UsersInRoles a une relation avec User :
    /// UsersInRoles est le ForeignType
    /// UsersInRoles.User est le ForeignProperty
    /// User est le PrimaryType
    /// User.UserName est le PrimaryProperty</example>
    /// </summary>
    public class OneToManyRelation
    {
        #region Fields

        #endregion

        #region .ctors


        internal OneToManyRelation(Guid pPrimaryPropertyID, Guid pPrimaryTypeID,
            Guid pForeignPropertyID, Guid pForeignTypeID, string pPrimaryPropertyName
            , string pPrimaryTypeName
            , string pForeignPropertyName
            , string pForeignTypeName
            , bool pForeignTypeIsManyToMany
            , bool pIsUsed)
        {
            //TODO: Refactoring de cette classe pour qu'elle utilise le NodeTypeManager
            PrimaryPropertyID = pPrimaryPropertyID;
            ForeignPropertyID = pForeignPropertyID;

            PrimaryTypeID = pPrimaryTypeID;
            PrimaryTypeName = pPrimaryTypeName;
            PrimaryPropertyName = pPrimaryPropertyName;
            ForeignTypeID = pForeignTypeID;
            ForeignPropertyName = pForeignPropertyName;
            ForeignTypeName = pForeignTypeName;
            ForeignTypeIsManyToMany = pForeignTypeIsManyToMany;
            IsUsed = pIsUsed;
        }

        #endregion

        #region Properties

        public Guid PrimaryPropertyID { get; set; }

        public Guid ForeignPropertyID { get; set; }

        public Guid PrimaryTypeID
        {
            get;
            internal set;
        }

        private NodeType _primaryType;
        protected NodeType PrimaryType
        {
            get
            {
                if (_primaryType == null)
                {
                    _primaryType = NodeTypeManager.GetNodeType(PrimaryTypeID);
                    if (_primaryType == null)
                    {
                        throw new CoreException("NodeType not found : " + PrimaryTypeID); 
                    }
                }
                return _primaryType;
            }
        }

        public string PrimaryPropertyName
        {
            get;
            internal set;
        }

        public string PrimaryTypeName
        {
            get;
            internal set;
        }

        public Guid ForeignTypeID
        {
            get;
            internal set;
        }

        private NodeType _foreignType;
        protected NodeType ForeignType
        {
            get
            {
                if (_foreignType == null)
                {
                    _foreignType = NodeTypeManager.GetNodeType(ForeignTypeID);
                    if (_foreignType == null)
                    {
                        throw new CoreException("NodeType not found : " + ForeignTypeID);
                    }
                }
                return _foreignType;
            }
        }

        private NodeTypeProperty _foreignProperty;
        public NodeTypeProperty ForeignProperty
        {
            get
            {
                if(_foreignProperty == null)
                {
                    _foreignProperty = NodeTypeManager.GetTypeProperty(ForeignPropertyID);
                }
                return _foreignProperty;
            }
        }

        public string ForeignPropertyName
        {
            get;
            internal set;
        }

        public string ForeignTypeName
        {
            get;
            internal set;
        }

        public bool ForeignTypeIsManyToMany { get; internal set; }
        public bool PrimaryTypeIsManyToMany
        {
            get
            {
                return PrimaryType.IsManyToMany;
            }
        }

        public bool IsUsed { get; private set; }

        #endregion

        #region Methods

        
        public NodeTypeProperty GetForeignProperty()
        {
            return NodeTypeManager.GetTypeProperty(this.ForeignPropertyID);
        }

        #endregion
    }

    
}
